<template>
  <BasicModal width="800px" :title="t('component.upload.upload')" :okText="t('component.upload.save')" v-bind="$attrs"
    @register="register" @ok="handleOk" :closeFunc="handleCloseFunc" :maskClosable="false" :keyboard="false"
    class="upload-modal" :okButtonProps="getOkButtonProps" :cancelButtonProps="{ disabled: isUploadingRef }">
    <template #centerFooter>
      <a-button @click="handleStartUpload" :disabled="!getIsSelectFile" :loading="isUploadingRef">
        {{ getUploadBtnText }}
      </a-button>
    </template>

    <div class="upload-modal-toolbar">
      <Alert :message="getHelpText" type="info" banner class="upload-modal-toolbar__text" />

      <Upload :accept="getStringAccept" :multiple="multiple" :before-upload="beforeUpload" :show-upload-list="false"
        class="upload-modal-toolbar__btn">
        <a-button type="primary">
          {{ t('component.upload.choose') }}
        </a-button>
      </Upload>
    </div>
    <FileList v-model:dataSource="fileListRef" :columns="columns" :actionColumn="actionColumn"
      :openDrag="fileListOpenDrag" :dragOptions="fileListDragOptions" />
  </BasicModal>
</template>
<script lang="ts" setup>
import { ref, toRefs, unref, computed, PropType } from 'vue';
import { Upload, Alert } from 'ant-design-vue';
import { BasicModal, useModalInner } from '@/components/Modal';
// hooks
import { useUploadType } from '../../hooks/useUpload';
import { useMessage } from '@/hooks/web/useMessage';
//   types
import { FileItem, UploadResultStatus } from '../../types/typing';
import { basicProps } from '../../props';
import { createTableColumns, createActionColumn } from '../data';
// utils
import { checkImgType, getBase64WithFile } from '../../helper';
import { buildUUID } from '@/utils/uuid';
import { isFunction } from '@/utils/is';
import { warn } from '@/utils/log';
import FileList from '../FileList.vue';
import { useI18n } from '@/hooks/web/useI18n';

const props = defineProps({
  ...basicProps,
  previewFileList: {
    type: Array as PropType<string[]>,
    default: () => [],
  },
});

const emit = defineEmits(['change', 'register', 'delete']);

const columns = createTableColumns();
const actionColumn = createActionColumn(handleRemove);

// 是否正在上传
const isUploadingRef = ref(false);
const fileListRef = ref<FileItem[]>([]);
const { accept, helpText, maxNumber, maxSize } = toRefs(props);

const { t } = useI18n();
const [register, { closeModal }] = useModalInner();

const { getStringAccept, getHelpText } = useUploadType({
  acceptRef: accept,
  helpTextRef: helpText,
  maxNumberRef: maxNumber,
  maxSizeRef: maxSize,
});

const { createMessage } = useMessage();

const getIsSelectFile = computed(() => {
  return (
    fileListRef.value.length > 0 &&
    !fileListRef.value.every((item) => item.status === UploadResultStatus.SUCCESS)
  );
});

const getOkButtonProps = computed(() => {
  const someSuccess = fileListRef.value.some(
    (item) => item.status === UploadResultStatus.SUCCESS,
  );
  return {
    disabled: isUploadingRef.value || fileListRef.value.length === 0 || !someSuccess,
  };
});

const getUploadBtnText = computed(() => {
  const someError = fileListRef.value.some((item) => item.status === UploadResultStatus.ERROR);
  return isUploadingRef.value
    ? t('component.upload.uploading')
    : someError
      ? t('component.upload.reUploadFailed')
      : t('component.upload.startUpload');
});

// 上传前校验
function beforeUpload(file: File) {
  const { size, name } = file;
  const { maxSize } = props;
  // 设置最大值，则判断
  if (maxSize && file.size / 1024 / 1024 >= maxSize) {
    createMessage.error(t('component.upload.maxSizeMultiple', [maxSize]));
    return false;
  }

  const commonItem = {
    uuid: buildUUID(),
    file,
    size,
    name,
    percent: 0,
    type: name.split('.').pop(),
  };
  // 生成图片缩略图
  if (checkImgType(file)) {
    // beforeUpload，如果异步会调用自带上传方法
    // file.thumbUrl = await getBase64(file);
    getBase64WithFile(file).then(({ result: thumbUrl }) => {
      fileListRef.value = [
        ...unref(fileListRef),
        {
          thumbUrl,
          ...commonItem,
        },
      ];
    });
  } else {
    fileListRef.value = [...unref(fileListRef), commonItem];
  }
  return false;
}

// 删除
function handleRemove(record: FileItem) {
  const index = fileListRef.value.findIndex((item) => item.uuid === record.uuid);
  index !== -1 && fileListRef.value.splice(index, 1);
  emit('delete', record);
}

async function uploadApiByItem(item: FileItem) {
  // console.log('file upload', item);

  const { api } = props;
  if (!api || !isFunction(api)) {
    return warn('upload api must exist and be a function');
  }
  try {
    item.status = UploadResultStatus.UPLOADING;
    const formData = new FormData();
    formData.append('file', item.file);
    await props.api?.(formData);
    // const ret = await props.api?.(
    //   {
    //     data: {
    //       ...(props.uploadParams || {}),
    //     },
    //     file: item.file,
    //     name: item.name,
    //     filename: item.file.name,
    //   }
    // );

    item.status = UploadResultStatus.SUCCESS;
    // item.response = { code: 20000, message: 'success', url: '' };
    return {
      success: true,
      error: null,
    };
  } catch (e) {
    console.log(e);
    item.status = UploadResultStatus.ERROR;
    return {
      success: false,
      error: e,
    };
  }
}

// 点击开始上传
async function handleStartUpload() {
  const { maxNumber } = props;
  if ((fileListRef.value.length + props.previewFileList?.length ?? 0) > maxNumber) {
    return createMessage.warning(t('component.upload.maxNumber', [maxNumber]));
  }
  try {
    isUploadingRef.value = true;
    // 只上传不是成功状态的
    const uploadFileList =
      fileListRef.value.filter((item) => item.status !== UploadResultStatus.SUCCESS) || [];
    const data = await Promise.all(
      uploadFileList.map((item) => {
        return uploadApiByItem(item);
      }),
    );
    isUploadingRef.value = false;
    // 生产环境:抛出错误
    const errorList = data.filter((item: any) => !item.success);
    if (errorList.length > 0) throw errorList;
  } catch (e) {
    isUploadingRef.value = false;
    throw e;
  }
}

//   点击保存
function handleOk() {
  // const { maxNumber } = props;

  // if (fileListRef.value.length > maxNumber) {
  //   return createMessage.warning(t('component.upload.maxNumber', [maxNumber]));
  // }
  // if (isUploadingRef.value) {
  //   return createMessage.warning(t('component.upload.saveWarn'));
  // }
  // const fileList: string[] = [];

  // // for (const item of fileListRef.value) {
  // //   const { status, response } = item;
  // //   if (status === UploadResultStatus.SUCCESS && response) {
  // //     fileList.push(response);
  // //   }
  // // }
  // // 存在一个上传成功的即可保存
  // if (fileList.length <= 0) {
  //   return createMessage.warning(t('component.upload.saveError'));
  // }
  // fileListRef.value = [];
  emit('change', ['1']);
  closeModal();
}

// 点击关闭：则所有操作不保存，包括上传的
async function handleCloseFunc() {
  if (!isUploadingRef.value) {
    fileListRef.value = [];
    return true;
  } else {
    createMessage.warning(t('component.upload.uploadWait'));
    return false;
  }
}
</script>
<style lang="less">
.upload-modal {
  .ant-upload-list {
    display: none;
  }

  .ant-table-wrapper .ant-spin-nested-loading {
    padding: 0;
  }

  &-toolbar {
    display: flex;
    align-items: center;
    margin-bottom: 8px;

    &__btn {
      flex: 1;
      margin-left: 8px;
      text-align: right;
    }
  }
}
</style>
